home *** CD-ROM | disk | FTP | other *** search
/ Over 1,000 Windows 95 Programs / Over 1000 Windows 95 Programs (Microforum) (Disc 1).iso / 1157 / source / componen / dtrans.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1996-11-07  |  13.2 KB  |  416 lines

  1. unit Dtrans;
  2.  
  3. interface
  4.  
  5. {
  6.   DelphiTranslator Component
  7.   Allow you to translate all string properties at design (and run)time.
  8.  
  9.   Simply put it on your Form,
  10.   set the property FileName to 'test.lng'
  11.   change property Language to 2,
  12.   modify e.g. the Form.Caption and
  13.   change property Language back to 1 ...
  14.  
  15.   not public release V 0.2, Copyright Matthias Weingart 1996
  16.   matthias@penthouse.boerde.de
  17.  
  18.   to do:
  19.   renamed to TLanguageSwitcher, done :-)
  20.   translate TStringLists
  21.   language file location with project path or store in StringList?
  22.   Message to other TLanguageSwitcher-Components to Update Language, recognize that not all forms are open 
  23.   special string component
  24.  
  25. }
  26.  
  27. uses
  28.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  29.   Forms, Dialogs, TypInfo, DebugBox;
  30.  
  31. type
  32.   TLanguageCount = 1..100;
  33.  
  34.   TTreatPropertyFunction = procedure ( Component: TComponent; PropInfo : PPropInfo;
  35.                                        const PropName : string; ALanguage: TLanguageCount
  36.                                       ) of object;
  37.  
  38.   TLanguageSwitcher = class(TComponent)
  39.   private
  40.     { Private-Deklarationen }
  41.    FFileName : string;
  42.    FMaxLanguageCount : TLanguageCount;
  43.    List: TStringList;
  44.    FLanguage : TLanguageCount;
  45.   protected
  46.     { Protected-Deklarationen }
  47.     StartComponent: TComponent;
  48.     LanguageIdx: TLanguageCount;
  49.     TreatPropertyFunction: TTreatPropertyFunction;
  50.  
  51.    Procedure SetLanguage(ALanguage : TLanguageCount);
  52.    Procedure SetMaxLanguageCount(AMaxLanguageCount : TLanguageCount);
  53.    Procedure SetFileName(AFileName : String);
  54.  
  55.     procedure TreatPropertyGet( Component:TComponent;
  56.                                    PropInfo : PPropInfo; const PropName : string; ALanguage: TLanguageCount );
  57.     procedure TreatPropertySet( Component:TComponent;
  58.                                    PropInfo : PPropInfo; const PropName : string; ALanguage: TLanguageCount );
  59.     procedure TreatPropertyCreate( Component:TComponent;
  60.                                    PropInfo : PPropInfo; const PropName : string; ALanguage: TLanguageCount );
  61.     procedure TreatProperty( Component:TComponent; PropInfo : PPropInfo; Name : string );
  62.     procedure IterateProperties( Component : TComponent; TypeKinds: TTypeKinds; Name: string );
  63.     procedure IterateComponents( Component : TComponent; TypeKinds: TTypeKinds; Name: string);
  64.     procedure PropertyCreate( aList: TStringList; Component: TComponent );
  65.     procedure PropertySet( aList: TStringList; Component: TComponent; aLanguageIdx: TLanguageCount );
  66.     procedure PropertyGet( aList: TStringList; Component: TComponent; aLanguageIdx: TLanguageCount );
  67.     procedure ReadHeader;
  68.     procedure ReadList;
  69.     procedure WriteList;
  70.     procedure LanguageChange( Old, New: TLanguageCount);
  71.     procedure MaxLanguageCountChange( AMaxLanguageCount: TLanguageCount );
  72.     procedure FileNameChange;
  73.  
  74.   public
  75.     { Public-Deklarationen }
  76.     constructor Create(AOwner: TComponent); override;
  77.  
  78.   published
  79.     { Published-Deklarationen }
  80.    Property Language : TLanguageCount Read FLanguage Write SetLanguage Default 1;
  81.    Property MaxLanguageCount : TLanguageCount Read FMaxLanguageCount Write SetMaxLanguageCount Default 1;
  82.    Property FileName : String Read FFileName Write SetFileName;
  83.   end;
  84.  
  85. procedure Register;
  86.  
  87. implementation
  88.  
  89. procedure Register;
  90. begin
  91.   RegisterComponents('Samples', [TLanguageSwitcher]);
  92. end;
  93.  
  94. constructor TLanguageSwitcher.Create(AOwner: TComponent);
  95. begin
  96.     inherited Create( AOwner );
  97.     StartComponent := GetParentForm(Self.Owner as TControl); { the form where it is }
  98.     if StartComponent = nil then
  99.        Application.MessageBox('No Parent Form!', 'TLanguageSwitcher', mb_OK );
  100.     TreatPropertyFunction:=nil;
  101.     FLanguage:=1;
  102.     FMaxLanguageCount:=2;
  103.     List:=nil;
  104. end;
  105.  
  106. Procedure TLanguageSwitcher.SetLanguage(ALanguage : TLanguageCount);
  107. var Old: TLanguageCount;
  108. Begin
  109.    If (ALanguage <= MaxLanguageCount) and (ALanguage>=Low(TLanguageCount)) Then
  110.    Begin
  111.          Old:= FLanguage;
  112.          FLanguage := ALanguage;
  113.          LanguageChange( Old, ALanguage );
  114.    End;
  115. End;
  116.  
  117. Procedure TLanguageSwitcher.SetMaxLanguageCount(AMaxLanguageCount : TLanguageCount);
  118. Begin
  119.    if AMaxLanguageCount = FMaxLanguageCount then exit;
  120.    If AMaxLanguageCount < FMaxLanguageCount Then
  121.    Begin
  122.       if (Application.MessageBox('Reduzing the number of languages will delete other languages. Sure?',
  123.                                  'Warning!', mb_OKCancel )
  124.           <>IDOK) then
  125.           exit;
  126.    End;
  127.    if (not (csLoading in ComponentState)) then
  128.       MaxLanguageCountChange( AMaxLanguageCount );
  129. End;
  130.  
  131.  
  132. Procedure TLanguageSwitcher.SetFileName(AFileName : String);
  133. Begin
  134.    If AFileName <> FFileName Then
  135.    Begin
  136.          FFileName := AFileName;
  137.          if FileExists( FFileName ) then
  138.          begin {read file}
  139.             if (not (csLoading in ComponentState)) then
  140.                FileNameChange;
  141.          end;
  142.    End;
  143. End;
  144.  
  145. procedure TLanguageSwitcher.TreatPropertyCreate( Component:TComponent;
  146.                                                  PropInfo : PPropInfo; const PropName : string; ALanguage: TLanguageCount );
  147. var
  148.   i: TLanguageCount;
  149.   SubList: TStringList;
  150. begin
  151.        SubList:=TStringList.Create;
  152.        for i:=1 to MaxLanguageCount do
  153.            SubList.Add( GetStrProp( Component, PropInfo ) );
  154.        List.AddObject(PropName, SubList);
  155. end;
  156.  
  157. procedure TLanguageSwitcher.TreatPropertyGet( Component:TComponent;
  158.                                                  PropInfo : PPropInfo; const PropName : string; ALanguage: TLanguageCount );
  159. var
  160.   i: TLanguageCount;
  161.   SubList: TStringList;
  162.   idx: Integer;
  163. begin { the stringproperty GETs the value from the list}
  164.      if List.Find( PropName, idx ) then
  165.      begin
  166.         SubList:=TStringList( List.Objects[idx] );
  167.         SetStrProp( Component, PropInfo, SubList.Strings[ ALanguage-1 ] );
  168.      end;{ else warning}
  169. end;
  170.  
  171. procedure TLanguageSwitcher.TreatPropertySet( Component:TComponent;
  172.                                                  PropInfo : PPropInfo; const PropName : string; ALanguage: TLanguageCount );
  173. var
  174.   i: TLanguageCount;
  175.   SubList: TStringList;
  176.   idx: Integer;
  177. begin { the value in the list ist SET from the StringProperty }
  178.      if List.Find( PropName, idx ) then
  179.      begin
  180.         SubList:=TStringList( List.Objects[idx] );
  181.         if ALanguage-1<SubList.Count then
  182.            SubList.Strings[ ALanguage-1 ] := GetStrProp( Component, PropInfo )
  183.         else {Language is new, add the actual selected values}
  184.            SubList.Add(GetStrProp( Component, PropInfo ));
  185.      end else {Property is new}
  186.         TreatPropertyCreate( Component, PropInfo, PropName, ALanguage );
  187. end;
  188.  
  189. procedure TLanguageSwitcher.TreatProperty( Component:TComponent; PropInfo : PPropInfo; Name : string );
  190. var
  191.   n:string;
  192.   l:byte;
  193.   PropName: string;
  194. begin
  195.   if PropInfo = nil then Exit;
  196.   n:=PropInfo^.PropType^.Name;
  197.   if (PropInfo^.PropType^.Kind = tkString) and
  198.      (PropInfo^.PropType^.Name <> 'TComponentName') then
  199.   begin
  200.        l:=GetTypeData(PropInfo^.PropType)^.MaxLength;
  201.        PropName:=Name+PropInfo^.Name+'['+IntToStr(l)+']';
  202.        TreatPropertyFunction( Component, PropInfo, PropName, LanguageIdx );
  203.   end;
  204.   {handle Stringlist here, Liste in einzelne Strings zerpfluecken, ist tkClass}
  205. end;
  206.  
  207. procedure TLanguageSwitcher.IterateProperties( Component : TComponent; TypeKinds: TTypeKinds; Name: string );
  208. var
  209.    j : Integer;
  210.    FCount, FSize : integer;
  211.    FList : PPropList;
  212. begin
  213.   FCount := GetPropList(Component.ClassInfo, TypeKinds, nil);
  214.   FSize := FCount * SizeOf(Pointer);
  215.   GetMem(FList, FSize);
  216.   GetPropList(Component.ClassInfo, TypeKinds, FList);
  217.  
  218.   for j:=0 to FCount-1 do
  219.   begin
  220.     TreatProperty( Component, FList^[ j ], Name );
  221.   end;
  222.   FreeMem( FList, FSize );
  223. end;
  224.  
  225. function GetComponentName(Component : TComponent): string;
  226. begin
  227.    Result:=Component.Name;
  228.    if Result='' then
  229.       Result:='('+Component.ClassName+')';
  230. end;
  231.  
  232. procedure TLanguageSwitcher.IterateComponents( Component : TComponent; TypeKinds: TTypeKinds; Name: string);
  233. var i:integer;
  234. begin
  235.      Name:=Name+GetComponentName(Component)+'.';
  236.      IterateProperties( Component, TypeKinds, Name ); { properties of the form }
  237.      for i:=0 to Component.ComponentCount-1 do
  238.      begin { properties of the components at the form }
  239.       if Component.Components[i].ClassName<>'TLanguageSwitcher' then
  240.       begin
  241.        IterateProperties( Component.Components[i], TypeKinds,
  242.                           Name + GetComponentName(Component.Components[i])+'.');
  243.       end;
  244.      end;
  245. end;
  246.  
  247. procedure TLanguageSwitcher.PropertyCreate( aList: TStringList; Component: TComponent );
  248. begin
  249.      TreatPropertyFunction:=TreatPropertyCreate;
  250.      List:=aList;
  251.      IterateComponents( Component, [tkString], '' );
  252. end;
  253.  
  254. procedure TLanguageSwitcher.PropertySet( aList: TStringList; Component: TComponent; aLanguageIdx: TLanguageCount );
  255. begin
  256.      TreatPropertyFunction:=TreatPropertySet;
  257.      List:=aList;
  258.      LanguageIdx:=aLanguageIdx;
  259.      IterateComponents( Component, [tkString], '' );
  260. end;
  261.  
  262. procedure TLanguageSwitcher.PropertyGet( aList: TStringList; Component: TComponent; aLanguageIdx: TLanguageCount );
  263. begin
  264.      TreatPropertyFunction:=TreatPropertyGet;
  265.      List:=aList;
  266.      LanguageIdx:=aLanguageIdx;
  267.      IterateComponents( Component, [tkString], '' );
  268. end;
  269.  
  270. procedure WriteSList( var f: TextFile; List: TStringList; Nsub: Integer );
  271. var i,k:integer;
  272.     SubList: TStringList;
  273. begin
  274.      for i:=0 to List.Count-1 do
  275.      begin
  276.          WriteLn(f, List.Strings[i] );
  277.          if List.Objects[i] is TStringList then
  278.          begin
  279.            SubList:= TStringList( List.Objects[i] );
  280.            for k:=0 to Nsub-1 do
  281.            begin
  282.              if k<SubList.Count then
  283.                WriteLn(f, Sublist.Strings[k] )
  284.              else
  285.                if SubList.Count>0 then
  286.                   WriteLn(f, Sublist.Strings[0] )
  287.                else
  288.                   WriteLn(f, '' );
  289.            end;
  290.          end;
  291.      end;
  292. end;
  293.  
  294. procedure ReadSList( var f: TextFile; List: TStringList; Nsub: Integer );
  295. var s: string;
  296.     SubList: TStringList;
  297.     k: integer;
  298. begin
  299.      while not EOF(f) do
  300.      begin
  301.          SubList:=TStringList.Create;
  302.          ReadLn(f, s);
  303.          List.AddObject(s, SubList);
  304.          for k:=0 to Nsub-1 do
  305.          begin
  306.               ReadLn(f, s);
  307.               SubList.Add(s);
  308.          end;
  309.      end;
  310. end;
  311.  
  312. procedure TLanguageSwitcher.ReadHeader;
  313. var
  314.     f: TextFile;
  315.     i1,i2: TLanguageCount;
  316. begin
  317.            AssignFile( f, FileName);
  318.            Reset( f );
  319.            Readln( f, i1, i2 ); {read header}
  320.            FMaxLanguageCount:=i2; {do nothing!}
  321.            FLanguage:=i1;
  322.            CloseFile( f );
  323. end;
  324.  
  325. procedure TLanguageSwitcher.ReadList;
  326. var
  327.     f: TextFile;
  328. begin
  329.      AssignFile( f, FileName);
  330.      Reset( f );
  331.      Readln( f ); {read header as dummy}
  332.      ReadSList( f, List, MaxLanguageCount );
  333.      CloseFile( f );
  334. end;
  335.  
  336. procedure TLanguageSwitcher.WriteList;
  337. var
  338.     f: TextFile;
  339. begin
  340.      AssignFile( f, FileName);
  341.      Rewrite( f );
  342.      Writeln( f, Language, ' ',MaxLanguageCount );
  343.      WriteSList( f, List, MaxLanguageCount );
  344.      CloseFile( f );
  345. end;
  346.  
  347. procedure TLanguageSwitcher.LanguageChange( Old, New: TLanguageCount);
  348. begin
  349.  if (Old<>New) then begin
  350.   if (Filename<>'') then begin
  351.      List:= TStringList.Create;
  352.      List.Sorted:=True;
  353.      List.Duplicates:=dupAccept;
  354.      if FileExists( FileName ) then
  355.      begin
  356.           ReadList;
  357.           PropertySet( List, StartComponent, Old ); {store old Values in file}
  358.           PropertyGet( List, StartComponent, New ); {get new Values from file}
  359.           WriteList;
  360.      end else begin
  361.          PropertyCreate( List, StartComponent );
  362.          WriteList;
  363.      end;
  364.      List.Free; List:=nil;
  365.   end;
  366.  end;
  367. end;
  368.  
  369. procedure TLanguageSwitcher.MaxLanguageCountChange( AMaxLanguageCount: TLanguageCount );
  370. var
  371.    Enlarge: boolean;
  372. begin
  373.   if (Filename<>'') then begin
  374.      List:= TStringList.Create;
  375.      List.Sorted:=True;
  376.      List.Duplicates:=dupAccept;
  377.      if FileExists( FileName ) then
  378.      begin
  379.           ReadList;
  380.           PropertySet( List, StartComponent, Language ); {store old Values in file}
  381.      end else begin
  382.          PropertyCreate( List, StartComponent);
  383.      end;
  384.      {Change Count}
  385.      Enlarge:=FMaxLanguageCount < AMaxLanguageCount;
  386.      FMaxLanguageCount := AMaxLanguageCount;
  387.      if Enlarge then
  388.         PropertySet( List, StartComponent, MaxLanguageCount ); {create New Entries}
  389.      WriteList;
  390.      List.Free; List:=nil;
  391.   end;
  392. end;
  393.  
  394. procedure TLanguageSwitcher.FileNameChange;
  395. begin
  396.   if (Filename<>'') then begin
  397.      List:= TStringList.Create;
  398.      List.Sorted:=True;
  399.      List.Duplicates:=dupAccept;
  400.      if FileExists( FileName ) then
  401.      begin
  402.           ReadHeader; { get: Language and MaxLanguageCount }
  403.           ReadList;
  404.           PropertyGet( List, StartComponent, Language ); {get new Values from file}
  405.           WriteList;
  406.      end else begin
  407.          PropertyCreate( List, StartComponent );
  408.          WriteList;
  409.      end;
  410.      List.Free; List:=nil;
  411.   end;
  412. end;
  413.  
  414.  
  415. end.
  416.